// #include <erl_nif.h>
// #include <opus/opusfile.h>
// #include <opus/opusenc.h>
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>

// // 定义错误处理宏
// #define CHECK_NULL(ptr, msg) \
//     if (!(ptr)) { \
//         fprintf(stderr, "Error: %s\n", msg); \
//         return NULL; \
//     }

// #define CHECK_ERROR(cond, msg) \
//     if (!(cond)) { \
//         fprintf(stderr, "Error: %s\n", msg); \
//         return -1; \
//     }

// // 创建 Opus 编码器
// static OggOpusEnc* create_opus_encoder(ErlNifEnv* env, ErlNifBinary* output, int sample_rate, int channels) {
//     int error = 0;
//     OggOpusEnc* enc = ope_encoder_create_pull(NULL, sample_rate, channels, 0, &error);
//     CHECK_NULL(enc, "Failed to create Opus encoder");
//     return enc;
// }

// static int opus_to_ogg(ErlNifEnv* env, ErlNifBinary* ogg_data, ErlNifBinary* output) {
//     OggOpusFile* of = op_open_memory(ogg_data->data, ogg_data->size, 0);
//     CHECK_NULL(of, "Failed to open OGG file");

//     // int channels = opus_file_get_channels(of);
//     // int sample_rate = opus_file_get_rate(of);
//     int channels = 1;
//     int sample_rate = 16000;

//     OggOpusEnc* enc = create_opus_encoder(env, output, sample_rate, channels);
//     CHECK_NULL(enc, "Failed to create Opus encoder");

//     ogg_packet op;
//     op.packet = (unsigned char*)ogg_data->data;
//     op.bytes = ogg_data->size;
//     op.b_o_s = 1;
//     op.e_o_s = 0;
//     op.granulepos = 0;
//     op.packetno = 0;

//     int ret = ope_encoder_write(enc, (const opus_int16*)op.packet, op.bytes / 2);
//     CHECK_ERROR(ret == 0, "Failed to write data to Opus encoder");

//     opus_file_close(of);
//     ope_encoder_drain(enc);
//     ope_encoder_destroy(enc);

//     return 0;
// }

// // 定义 NIF 函数
// static ERL_NIF_TERM opus_trans_ogg(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
//     ErlNifBinary ogg_bin;
//     ErlNifBinary output_bin;

//     // 获取输入的 Ogg 二进制流
//     if (!enif_inspect_binary(env, argv[0], &ogg_bin)) {
//         return enif_make_badarg(env);
//     }

//     output_bin.data = malloc(ogg_bin.size * 2);  // 假设输出大小不会超过输入的两倍
//     output_bin.size = ogg_bin.size * 2;

//     if (opus_to_ogg(env, &ogg_bin, &output_bin) != 0) {
//         free(output_bin.data);
//         return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Failed to transcode Ogg to Opus", ERL_NIF_LATIN1));
//     }

//     ERL_NIF_TERM output_term = enif_make_binary(env, &output_bin);
//     free(output_bin.data);
//     return enif_make_tuple2(env, enif_make_atom(env, "ok"), output_term);
// }

// // NIF 初始化函数
// static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) {
//     return 0;
// }

// // NIF 卸载函数
// static void unload(ErlNifEnv* env, void* priv_data) {
// }

// // NIF 函数表
// static ErlNifFunc nif_funcs[] = {
//     {"opus_trans_ogg", 1, opus_trans_ogg}
// };

// // NIF 模块定义
// ERL_NIF_INIT(Elixir.SockWorkstation.OpusTransOggNif, nif_funcs, &load, NULL, NULL, &unload)


#include <erl_nif.h>
#include <opus/opusfile.h>
#include <opus/opusenc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义错误处理宏
#define CHECK_NULL(ptr, msg) \
    if (!(ptr)) { \
        fprintf(stderr, "Error: %s\n", msg); \
        return NULL; \
    }

#define CHECK_ERROR(cond, msg) \
    if (!(cond)) { \
        fprintf(stderr, "Error: %s\n", msg); \
        return -1; \
    }

// 创建 OGG 编码器
static OggOpusEnc* create_ogg_encoder(ErlNifEnv* env, ErlNifBinary* output, int sample_rate, int channels) {
    int error = 0;
    OggOpusEnc* enc = ope_encoder_create_pull(NULL, sample_rate, channels, 0, &error);
    CHECK_NULL(enc, "Failed to create OGG encoder");
    return enc;
}

// 编码 OPUS 二进制流到 OGG 流
static int opus_to_ogg(ErlNifEnv* env, ErlNifBinary* opus_data, ErlNifBinary* output) {
    OggOpusFile* of = op_open_memory(opus_data->data, opus_data->size, 0);
    CHECK_NULL(of, "Failed to open OPUS file");

    int channels = op_head_get_input_sample_rate(op_head(of, -1));
    int sample_rate = 48000; // 默认采样率

    OggOpusEnc* enc = create_ogg_encoder(env, output, sample_rate, channels);
    CHECK_NULL(enc, "Failed to create OGG encoder");

    ogg_packet op;
    op.packet = (unsigned char*)opus_data->data;
    op.bytes = opus_data->size;
    op.b_o_s = 1;
    op.e_o_s = 0;
    op.granulepos = 0;
    op.packetno = 0;

    int ret = ope_encoder_write(enc, (const opus_int16*)op.packet, op.bytes / 2);
    CHECK_ERROR(ret == 0, "Failed to write data to OGG encoder");

    op_free(of);
    ope_encoder_drain(enc);
    ope_encoder_destroy(enc);

    return 0;
}

// 定义 NIF 函数
static ERL_NIF_TERM opus_trans_ogg(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
    ErlNifBinary opus_bin;
    ErlNifBinary output_bin;

    // 获取输入的 OPUS 二进制流
    if (!enif_inspect_binary(env, argv[0], &opus_bin)) {
        return enif_make_badarg(env);
    }

    // 初始化输出的 OGG 二进制流
    output_bin.data = malloc(opus_bin.size * 2);  // 假设输出大小不会超过输入的两倍
    output_bin.size = opus_bin.size * 2;

    // 编码 OPUS 流到 OGG 流
    if (opus_to_ogg(env, &opus_bin, &output_bin) != 0) {
        free(output_bin.data);
        return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Failed to transcode OPUS to OGG", ERL_NIF_LATIN1));
    }

    // 返回 OGG 二进制流
    ERL_NIF_TERM output_term = enif_make_binary(env, &output_bin);
    free(output_bin.data);
    return enif_make_tuple2(env, enif_make_atom(env, "ok"), output_term);
}

// NIF 初始化函数
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) {
    return 0;
}

// NIF 卸载函数
static void unload(ErlNifEnv* env, void* priv_data) {
}

// NIF 函数表
static ErlNifFunc nif_funcs[] = {
    {"opus_trans_ogg", 1, opus_trans_ogg}
};

// NIF 模块定义
ERL_NIF_INIT(Elixir.SockWorkstation.OpusTransOggNif, nif_funcs, &load, NULL, NULL, &unload)